import 'dart:collection';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:wis_flutter/index.dart';        // wis flutter 组件 


// 下拉框  联动
class SelectCorrelateForm extends StatefulWidget {

    final dynamic controller;      // 表单名称
    final String label;           // lable
    final bool validator;         // 校验
    final String validatorText;   // 校验提示
    final bool readOnly;          // 只读
    final dynamic onChanged;    // 值改变
    final dynamic children;    // 组织树 数据
    final String defaultVal; // 默认值



    SelectCorrelateForm({
        Key key,
        this.controller,
        this.label,
        this.defaultVal,
        this.validator=false,
        this.validatorText="必填",
        this.readOnly=false,   
        this.onChanged,
        this.children,
    }) : super(key: key);  

    @override
    _SelectCorrelateFormState createState() => new _SelectCorrelateFormState();
}

class _SelectCorrelateFormState extends State<SelectCorrelateForm> {

    BuildContext _context;
    bool dialogActive=false;
    OverlayEntry overlayEntry;
    LayerLink layerLink = new LayerLink();

    List<Map<String, dynamic>> _list = [];   // 组织树 数据
    List _resultSelect=[];          // 表单数据
    String controllerText="";        // 选中数据
    String controllerTextInput="";        // 选中数据 input
    String _defaultVal="";          // 默认显示值


    // 初始化
    void initState() {
      super.initState();   
      this._defaultVal=widget.defaultVal;

      this._init();



      if( widget.children !=null ){
        // 模拟数据
        setState(() {
          _list =widget.children;      
        }); 
      }
     

      if( widget.defaultVal !=null ){
        setState(() {
          controllerText=_defaultVal;
          controllerTextInput=_defaultVal;
        });
      }

    }


    @override
    void dispose() {
      super.dispose();
    }    

    // 初始化 
    void _init(){
      // if( widget.controller.text != null ){
      //   // widget.controller.text=jsonEncode(_keyAll); 

      // }
    }

    // 修改表单
    void _editForm(result){
      List _keyAll=[];

      for (var i = 0; i < result.length; i++) {
        _keyAll.addAll([result[i]["key"]]);
      }

      
      setState(() {
        _resultSelect=_keyAll;
      });
    }

    // 打开
    void _onDialog1(context){

      if( this.dialogActive == false ){
        overlayEntry = createSelectPopupWindow();
        Overlay.of(context).insert(overlayEntry);
        FocusScope.of(context).requestFocus(FocusNode());
      }

      setState(() {
        dialogActive=true;
      });
   
    }

    // 保存
    void _saveFunc(){
      widget.controller.text=jsonEncode(_resultSelect); 

      setState(() {
        controllerTextInput=this.controllerText; 
      });



      //WisMessageGlobal.succeed(
      //  context:_context,
      //  title:"保存成功！",  
      //  duration:800,    
      //);

      this._removeOverlayEntry();    

    }

    // 清空
    void _emptyFunc(){

      

      //刷新
      overlayEntry.markNeedsBuild();

      setState(() {
        _resultSelect=[];
        controllerText="";
        controllerTextInput=""; 
      });      

      widget.controller.text=''; 
    }

    // 创建 弹框
    OverlayEntry createSelectPopupWindow() {
      OverlayEntry overlayEntry = OverlayEntry(builder: (context) {

        final size =MediaQuery.of(context).size;

        return Positioned(
          width: size.width*0.8,
          height: size.height,
          child: CompositedTransformFollower(
            offset: Offset(0.0, 50),
            link: layerLink,
            child: Material(
              child: Container(
                  padding: const EdgeInsets.fromLTRB(12,36,12,20),
                  color: Colors.white,
                  child: Stack(
                    children: <Widget>[

                      // 标题
                      Container(
                        child: Row(
                          children: <Widget>[
                            Expanded(
                              flex: 8,
                              child: Row(
                                children: <Widget>[
                                  Text(
                                    '单选',
                                    style: TextStyle(
                                      color: const Color.fromRGBO(81,90,110,1),
                                      fontWeight: FontWeight.w700,
                                      fontSize: 16
                                    ),
                                  ),
                                  Container(
                                    margin: const EdgeInsets.fromLTRB(20,10,0,0),
                                    child: (this._resultSelect.length>0)? InkWell(
                                      onTap: (){
                                        this._saveFunc();
                                      },
                                      child: Row(
                                        children: <Widget>[
                                          Icon( 
                                            Icons.done,
                                            size: 16, 
                                            color: Colors.blue,
                                          ),
                                          Text(
                                            " 保存",
                                            style: TextStyle(
                                              color: Colors.blue,
                                              fontSize: 14,
                                              fontWeight: FontWeight.w500,
                                            ),
                                          )
                                        ],
                                      ),
                                    ):Text(""),
                                  )
                                ],
                              )
                            ),
                            Expanded(
                              flex: 1,
                              child: IconButton(
                                icon: Icon(
                                  Icons.highlight_off,
                                  color: Color.fromARGB(255, 126, 126, 126), 
                                ),
                                onPressed: (){
                                  this._removeOverlayEntry();
                                }  
                              )
                            ),                              
                          ],
                        ),
                      ),

                      // 选中 
                      Container(
                        margin: EdgeInsets.fromLTRB(0,48,0,0),
                        child: Row(
                          children: <Widget>[
                            Expanded(
                              flex: 8,
                              child: Text(
                                '$controllerText',
                                overflow: TextOverflow.ellipsis,
                              )
                            ),
                            Expanded(
                              flex: 2,
                              // child: (this._resultSelect.length>0 || (controllerTextInput!=null&&controllerTextInput!="") )? InkWell(
                              child: InkWell(
                                onTap: (){
                                  this._emptyFunc();
                                },
                                child: Row(
                                  children: <Widget>[
                                    Icon( 
                                      Icons.delete_forever,
                                      size: 18, 
                                      color: Color.fromRGBO(237,64,20,1)
                                    ),
                                    Text(
                                      "清空",
                                      style: TextStyle(
                                        fontSize: 14,
                                        color: Color.fromRGBO(237,64,20,1)
                                      ),
                                    )
                                  ],
                                )
                              )
                            )
                          ],
                        ),
                      ),


                      Container(
                        padding: const EdgeInsets.fromLTRB(12,78,12,20),
                        child: WisTreePage(
                          height: 500,   // 高度  默认 300
                          children:this._list,
                          // 展开事件
                          onExpansionChanged: (key, expanded){
                            this._getParentAll(key);
                            // print(key);
                            // print(expanded);   //是否展开
                          },              
                          // 点击 最后一层
                          onClick:(key){
                            // print(key);
                            this._getParentAll(key);
                          }
                        ),
                      )

 
                    ]
                  )
                  
                  ),
            ),
          ),
        );
      });
      return overlayEntry;
    }


    // 关闭弹框
    void _removeOverlayEntry(){

      if( this.dialogActive == true ){
        overlayEntry.remove();
      }

      setState(() {
        dialogActive=false;     
      });

      Future.delayed(new Duration(milliseconds:500),(){
        setState(() {
          controllerText=controllerTextInput;     
        });
      });

    }


    // 获取 所有  父级 
    void _getParentAll(nowKey){

      var result= WisUtils.doRecurrence(nowKey, this._list);

      // 回调
      if( widget.onChanged!=null ){

        List _keyAll=[];
        for (var i = 0; i < result.length; i++) {
          _keyAll.add(result[i]["key"]);
        }
        widget.onChanged(_keyAll);
      }

      // 设置 表单
      this._editForm(result);



      // 显示
      var str="";

      for (var i = 0; i < result.length; i++) {
        str+=result[i]["label"]+" / ";
      }
    
      setState(() {
        controllerText=str;
      });

      //刷新
      overlayEntry.markNeedsBuild();
     
    }



    @override
    Widget build(BuildContext context) {
        this._context=context;

        return Padding(
          padding: EdgeInsets.fromLTRB(16,32,16,16),
          child:  Container(
            // color: Colors.white,
            child: Stack(
                children: <Widget>[

                  Container(
                    // padding: EdgeInsets.fromLTRB(0,0,0,16),
                    child: Row(
                      children: <Widget>[

                        Text(
                          widget.validator?'*':'',
                          textAlign: TextAlign.left,
                          overflow: TextOverflow.ellipsis,
                          style: TextStyle(
                              fontSize: 14,
                              color: Colors.red
                          )
                        ),  

                        Text(
                          widget.label.toString(),
                          overflow: TextOverflow.ellipsis,
                          style: TextStyle(
                              fontSize: 14,
                              color: const Color.fromRGBO(81,90,110,1)
                          ),
                        )
                      ],
                    ),
                  ),


                  Container(
                    margin: EdgeInsets.fromLTRB(0,26,0,0),
                    child: Row(
                      children: <Widget>[
                          Expanded(
                            child: TextFormField(
                              controller: widget.controller,
                              autofocus: false,
                              readOnly: true,
                              style: TextStyle(
                                color: Colors.transparent,
                              ),
                              decoration: InputDecoration(
                                  fillColor: Colors.black.withOpacity(0.05),
                                  filled: widget.readOnly,                                 
                                  // labelText: widget.label,
                                  labelStyle: TextStyle( 
                                      fontSize: 14.0, 
                                      color: Color.fromARGB(255, 93, 93, 93)
                                  ),
                                  enabledBorder: UnderlineInputBorder(
                                    borderSide: BorderSide(width:0.5,color: Colors.grey[500]),
                                  ),
                                  focusedBorder: UnderlineInputBorder(
                                    borderSide: BorderSide(width:0.5,color: Colors.blue),
                                  ),
                                  errorBorder: UnderlineInputBorder(
                                    borderSide: BorderSide(width:0.5,color: Colors.red),
                                  ),                                    
                              ),                              
                              validator: widget.validator ? (value) {
                                if (value.isEmpty) {
                                  return widget.validatorText;
                                }
                                return null;
                              }:null,
                            )
                          )
                      ],
                    ),
                  ),

                  InkWell(
                    onTap: (){
                      if( !widget.readOnly ){
                        FocusScope.of(context).requestFocus(FocusNode());
                        this._onDialog1(context);
                      }
                    },  
                    child: Container(
                      margin: EdgeInsets.fromLTRB(15,24,0,0),
                      height: 50,
                      child: Row(
                        children: <Widget>[
                          Expanded(
                            child: 
                              Padding(
                                padding: const EdgeInsets.fromLTRB(0,10,0,0),
                                child: Text(
                                  this.controllerTextInput.toString(),
                                  overflow: TextOverflow.ellipsis,
                                  style: TextStyle(
                                    fontSize: 16.0, 
                                    // height: 1.5,
                                  ),
                                )                             
                                // child:(widget.controller.text!='')? Text(
                                //   this.controllerTextInput,
                                //   overflow: TextOverflow.ellipsis,
                                //   style: TextStyle(
                                //     fontSize: 16.0, 
                                //     // height: 1.5,
                                //   ),
                                // ):Text('')                            
                              )
                          )
                        ],
                      ),
                    ) 
                  )  
                 
                ]
            )   
          )  
        );
    }  
}















class TreeData {
  String key;
  String label;
  List<TreeData> list;
  TreeData parent;

  TreeData({this.key, this.label, this.list, this.parent});

  addChild(TreeData treeData) {
    if (list == null) {
      list = new List();
    }
    list.add(treeData);
  }

  setParent(TreeData parent) {
    this.parent = parent;
  }
}

class WisUtils {
  static List<Map<String,String>> doRecurrence(String key,List _list) {
    Map<String, TreeData> treeMap = new HashMap();
    Map<String,String> map = new HashMap();
    List<Map<String,String>> result = new List();
    recurrence(treeMap, _list);
    if(treeMap.containsKey(key)){
      TreeData _parent = treeMap[key].parent;
      if(_parent != null){
        result =getAllNode(treeMap[key],result);
      }else{
        map["key"]= treeMap[key].key;
        map["label"]= treeMap[key].label;
        result.add(map);
      }
      return result;
    }else{
      return new List();
    }
  }

  static getAllNode(TreeData node,List<Map<String,String>> result){
    Map<String,String> map = new HashMap();
    if(node.parent != null){
       getAllNode(node.parent,result);
    }
    map["key"]=node.key;
    map["label"]=node.label;
    result.add(map);
    return result;

  }

  static Map<String, TreeData> recurrence(
      Map<String, TreeData> treeMap, List<Map<String, Object>> data,
      {String parentKey}) {
    data.forEach((element) {
      TreeData node =
          new TreeData(key: element['key'], label: element['label']);
      treeMap[element['key']] = node;
      if (parentKey != null && parentKey.isNotEmpty) {
        TreeData parent = treeMap[parentKey];
        parent.addChild(node);
        node.setParent(parent);
      }
      if (element['children'] != null) {
        recurrence(treeMap, element['children'], parentKey: element['key']);
      }
    });
    return treeMap;
  }
}
